Skip to content

Allow esbuild to reuse mangled property names in certain cases#4454

Open
LoganDark wants to merge 2 commits intoevanw:mainfrom
LoganDark:mangle-prop-namespaces
Open

Allow esbuild to reuse mangled property names in certain cases#4454
LoganDark wants to merge 2 commits intoevanw:mainfrom
LoganDark:mangle-prop-namespaces

Conversation

@LoganDark
Copy link
Copy Markdown

@LoganDark LoganDark commented Apr 18, 2026

Adds new options manglePropNamespaces and mangleNamespaceCaches along with corresponding tests. This allows esbuild to associate property names with a namespace during mangling, and reuse mangled names across namespaces, potentially resulting in bundle size savings. Namespaced caches are persisted to mangleNamespaceCaches when one is specified, and when --mangle-cache is specified via CLI, namespace caches are stored with a leading # like so (with another leading ^ for prefix matches and a trailing $ for suffix matches):

{
	"global_prop_": "a",
	"#^TypeA_": {
		"foo_": "b"
	},
	"#^TypeB_": {
		"foo_": "b"
	}
}

manglePropNamespaces is given a regular expression that matches on the property name to be mangled. If this regular expression matches, the match is treated as the property's namespace and the mangled name will be generated in that namespace (only avoiding collisions with others in the same namespace and with global properties).

Properties without a namespace are considered global, and will be given entirely unique mangled names (that do not conflict with any namespaces). Only namespaced properties will reuse mangled names from other namespaces - global properties will never reuse mangled names, and namespaced properties will never reuse mangled names of global properties.

The regular expression is expected to be anchored to either the start or the end of the property name. There is a basic check that such an anchor exists in the pattern, but if it manages to match in the middle of a property name anyway (e.g. ^start|sneaky), it is just treated as global. Also, RE2 doesn't support lookaheads, so if the namespace pattern matches the entire property name, then it is also treated as global.

Note that improper use can result in runtime errors, namely in cases where properties of different namespaces are mixed on the same object, or where code expecting properties from one namespace encounters properties from another namespace. Users are expected to know their use-case well enough to determine which properties to namespace or not.

In general, there's not really any harm to namespace collisions (i.e. two fields being in the same namespace when you didn't intend for them to be) other than perhaps missing some opportunities for name reuse, but there is harm in fields incorrectly being in different namespaces.

This PR has been generated with assistance from Claude, but the code has been manually audited and aggressively distilled, and I have successfully tested it with real projects.

I did not find contributing guidelines in the repo so please let me know if I missed anything.

Closes #4453

Patterns like ^abc|abc$ could have caused abc123 and 123abc to be cached
as a single name; treat them like separate namespaces for correctness.
@LoganDark LoganDark force-pushed the mangle-prop-namespaces branch from 70e7e91 to 6d13632 Compare April 18, 2026 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow esbuild to reuse mangled property names in certain cases

1 participant